using System.Transactions;
using AutoMapper;
using BaseData.Domain;
using BaseData.ErrorCode;
using BaseData.Infrastructrue.Interfaces;
using BaseData.WriteApi.Application.Command.Users;
using MD5Hash;
using MediatR;

namespace BaseData.WriteApi.Application.CommandHandler.Users
{
    /// <summary>
    /// 处理更新用户命令的命令处理器
    /// </summary>
    public class UpdateUserCommandHandler : IRequestHandler<UpdateUserCommand, Apiresult<int>>
    {
        private readonly IBasepository<UserInfo> userpository;  // 用户信息仓储接口
        private readonly IBasepository<Role> rolepository;  // 角色仓储接口
        private readonly IBasepository<UserRole> uRpository;  // 用户角色仓储接口
        private readonly IMapper mapper;  // 对象映射器
        private readonly ILogger<UpdateUserCommandHandler> logger;  // 日志记录器

        /// <summary>
        /// 构造函数，注入所需的服务
        /// </summary>
        /// <param name="_userpository">用户信息仓储</param>
        /// <param name="_rolepository">角色仓储</param>
        /// <param name="_URpository">用户角色仓储</param>
        /// <param name="_mapper">对象映射器</param>
        /// <param name="_logger">日志记录器</param>
        public UpdateUserCommandHandler(
            IBasepository<UserInfo> _userpository,
            IBasepository<Role> _rolepository,
            IBasepository<UserRole> _URpository,
            IMapper _mapper,
            ILogger<UpdateUserCommandHandler> _logger)
        {
            userpository = _userpository;
            rolepository = _rolepository;
            uRpository = _URpository;
            mapper = _mapper;
            logger = _logger;
        }

        /// <summary>
        /// 处理更新用户命令
        /// </summary>
        /// <param name="request">更新用户的请求数据</param>
        /// <param name="cancellationToken">取消标记</param>
        /// <returns>返回操作结果</returns>
        public async Task<Apiresult<int>> Handle(UpdateUserCommand request, CancellationToken cancellationToken)
        {
            // 开启事务处理
            using (var tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    // 查找要更新的用户
                    var user = await userpository.GetModel(u => u.UserId == request.UserId);
                    if (user == null)
                    {
                        return new Apiresult<int>
                        {
                            Code = ResultCode.查询失败,
                            Message = "用户不存在"
                        };
                    }

                    // 更新用户基本信息
                    user.UserName = request.UserName;
                    user.UserEmail = request.UserEmail;
                    user.NickName = request.NickName;
                    
                    // 如果提供了新密码，则更新密码
                    if (!string.IsNullOrEmpty(request.Password))
                    {
                        user.Password = request.Password.GetMD5();
                    }

                    // 更新用户数据
                    var userUpdateResult = await userpository.EditAsync(user);
                    if (userUpdateResult <= 0)
                    {
                        tran.Dispose();
                        return new Apiresult<int>
                        {
                            Code = ResultCode.修改失败,
                            Message = "用户信息更新失败"
                        };
                    }

                    // 查找用户当前的角色关联
                    var userRole = await uRpository.GetModel(ur => ur.UserId == request.UserId);
                    if (userRole != null)
                    {
                        // 如果角色ID发生变化，更新用户角色关联
                        if (userRole.RoleId != request.RoleId)
                        {
                            // 验证新角色是否存在
                            var newRole = await rolepository.GetModel(r => r.RoleId == request.RoleId);
                            if (newRole == null)
                            {
                                tran.Dispose();
                                return new Apiresult<int>
                                {
                                    Code = ResultCode.查询失败,
                                    Message = "角色不存在"
                                };
                            }

                            // 更新用户角色关联
                            userRole.RoleId = request.RoleId;
                            var roleUpdateResult = await uRpository.EditAsync(userRole);
                            if (roleUpdateResult <= 0)
                            {
                                tran.Dispose();
                                return new Apiresult<int>
                                {
                                    Code = ResultCode.修改失败,
                                    Message = "用户角色更新失败"
                                };
                            }
                        }
                    }
                    else
                    {
                        // 如果没有用户角色关联，创建新的关联
                        var newUserRole = new UserRole
                        {
                            UserId = request.UserId,
                            RoleId = request.RoleId
                        };
                        var roleInsertResult = await uRpository.InsertAsync(newUserRole);
                        if (roleInsertResult <= 0)
                        {
                            tran.Dispose();
                            return new Apiresult<int>
                            {
                                Code = ResultCode.添加失败,
                                Message = "用户角色添加失败"
                            };
                        }
                    }

                    // 提交事务
                    tran.Complete();
                    return new Apiresult<int>
                    {
                        Code = ResultCode.修改成功,
                        Message = "用户信息更新成功"
                    };
                }
                catch (Exception ex)
                {
                    // 发生异常时，回滚事务
                    tran.Dispose();
                    // 记录日志
                    logger.LogError($"UpdateUserCommandHandler.Handle方法异常：{ex.Message},{ex.StackTrace}");
                    return new Apiresult<int>
                    {
                        Code = ResultCode.修改失败,
                        Message = "系统异常，用户信息更新失败"
                    };
                }
            }
        }
    }
}